/*
    封装实现一个SqliteHelper类，提供简单的SQLite数据库操作接口，完成数据的增删查改操作
        1. 创建/打开数据库文件
        2. 针对打开的数据库执行擦欧总
            1. 对表的操作
            2. 对数据的操作
        3. 关闭数据库
*/ 

#include <sqlite3.h>
#include <string>
#include <iostream>

class SqliteHelper
{
public:
    /*  void*: 设置的在回调时传入的arg参数
        int: 数据的列数
        char**: 存储一行数据的字符指针数组
        char**: 每一列的字段名称
        回调函数的返回值在成功处理时返回0，返回非0则退出程序  */
    typedef int(*SqliteCallback)(void*, int, char**, char**);
    SqliteHelper(const std::string &dbfile) : _dbfile(dbfile), _handler(nullptr) // 数据库句柄是在打开后得到的
    {}
    bool open(int safeLevel = SQLITE_OPEN_FULLMUTEX)
    {
        // int sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, constchar *zVfs ); // ppDb是输入输出型参数
        int ret = sqlite3_open_v2(_dbfile.c_str(), &_handler, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | safeLevel, NULL);
        if(ret != SQLITE_OK)
        {
            std::cout << "创建/打开SQLite数据库失败：";
            std::cout << sqlite3_errmsg(_handler) << std::endl;
            return false;
        }
        return true;
    }
    bool exec(const std::string& sql, SqliteCallback cb, void* arg)
    {
        // int sqlite3_exec(sqlite3*, char *sql, int (*callback)(void*,int,char**,char**),void* arg, char **err)
        int ret = sqlite3_exec(_handler, sql.c_str(), cb, arg, nullptr);
        if(ret != SQLITE_OK)
        {
            std::cout << "执行语句失败：";
            std::cout << sqlite3_errmsg(_handler) << std::endl;
            return false;
        }
        return true;
    }
    void close()
    {
        if(_handler) sqlite3_close_v2(_handler);
    }
private:
    std::string _dbfile;
    sqlite3* _handler;
};